home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.12 Dec 96 / Async I⁄O Code / Sources / maker sources / DLOG 129.c next >
Encoding:
C/C++ Source or Header  |  1996-02-21  |  17.3 KB  |  707 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    Dialog Module, created by Resorcerer
  3.  */
  4.  
  5. #if 0
  6.     #include <Desk.h>
  7.     #include <DiskInit.h>
  8.     #include <Dialogs.h>
  9.     #include <Files.h>
  10.     #include <Fonts.h>
  11.     #include <Lists.h>
  12.     #include <Menus.h>
  13.     #include <Resources.h>
  14.     #include <Memory.h>
  15.     #include <OSUtils.h>
  16.     #include <OSEvents.h>
  17.     #include <Packages.h>
  18.     #include <Scrap.h>
  19.     #include <Script.h>
  20.     #include <SegLoad.h>
  21.     #include <stdio.h>
  22.     #include <ToolUtils.h>
  23.     #include <Values.h>
  24. #endif
  25.  
  26. #include <StdArg.h>
  27.  
  28. #define thisDialogID 129
  29.  
  30. /* Symbolic Dialog Item Numbers */
  31.  
  32. static enum {
  33.     BUT1_OK = 1,
  34.     BUT2_Cancel,
  35.     EDIT3,
  36.     STXT4_File,
  37.     STXT5_K,
  38.     LASTITEM
  39.     };
  40.  
  41. #define OK_ITEM     BUT1_OK
  42. #define CANCEL_ITEM     BUT2_Cancel
  43.  
  44. /* Useful constants */
  45.  
  46. #ifndef ENTERkey
  47. #define ENTERkey    0x3
  48. #endif
  49. #ifndef DELETEkey
  50. #define DELETEkey    0x8
  51. #endif
  52. #ifndef NIL
  53. #define NIL ((void *)0)
  54. #endif
  55. #ifndef TRUE
  56. #define TRUE 1
  57. #endif
  58. #ifndef FALSE
  59. #define FALSE 0
  60. #endif
  61. #ifndef FRONT_WINDOW
  62. #define FRONT_WINDOW  ((WindowPtr) (-1L))
  63. #endif
  64.  
  65. /* Prototypes */
  66.  
  67. int       DoDialog(void);
  68. DialogPtr OpenThisDialog(void);
  69. void      CloseThisDialog(DialogPtr dlog);
  70. void      DoDialogUpdate(DialogPtr dlog);
  71. void      DoDialogActivate(DialogPtr dlog, int activ);
  72. void      DoDialogContent(DialogPtr dlog, EventRecord *evt);
  73. int       DoDialogItem(DialogPtr dlog, short itemHit);
  74.  
  75. pascal  Boolean MyFilter(DialogPtr dlog, EventRecord *evt, short *itemHit);
  76. Boolean CheckUserItems(Point where, short *itemHit);
  77. int     AnyBadValues(DialogPtr dlog);
  78.  
  79. void    CenterWindow(WindowPtr w, int top);
  80. long    strlen(char *);
  81. char   *strcpy(char *dst, char *src);
  82. char   *PascalToC(char *pstr);
  83. char   *CToPascal(char *cstr);
  84. void    PutDlgString(DialogPtr dlog, int item, char *str, int sel);
  85. void    PutDlgWord(DialogPtr dlog, int item, int val, int sel);
  86. void    PutDlgLong(DialogPtr dlog, int item, long val, int sel);
  87. void    PutDlgChkRadio(DialogPtr dlog, int item, int val);
  88. int     GetDlgString(DialogPtr dlog, int item, char *str);
  89. int     GetDlgWord(DialogPtr dlog, int item, short *val);
  90. int     GetDlgLong(DialogPtr dlog, int item, long *val);
  91. int     GetDlgChkRadio(DialogPtr dlog, int item);
  92. int     TextSelected(DialogPtr dlog);
  93. OSType  CanPaste(int n, ...);
  94. void    FrameDefault(DialogPtr dlog, int item, int frame);
  95. void    GetDlgPanel(DialogPtr dlog, int item, Rect *panel);
  96.  
  97. static Point where;
  98. static int modifiers;
  99.  
  100. long        fileSize;
  101.  
  102. /*
  103.  *    Display this modal dialog.  Return TRUE if OK, FALSE if CANCEL or error.
  104.  *    If the dialog displays values from outside this module, you should either
  105.  *    import them from globals, or change the argument list of this routine to
  106.  *    bring them in and pass them to OpenThisDialog(), DoDialogItem(), etc.
  107.  */
  108.  
  109. int DoDialog()
  110.     {
  111.         short itemHit,okay,keepGoing=TRUE;
  112.         register DialogPtr dlog; GrafPtr oldPort;
  113.  
  114.         /* Build dialog window and install its item values */
  115.         
  116.         GetPort(&oldPort);
  117.         dlog = OpenThisDialog();
  118.         if (dlog == NIL) return(FALSE);
  119.  
  120.         /* Entertain filtered user events until dialog is dismissed */
  121.         
  122.         while (keepGoing) {
  123.             ModalDialog(MyFilter,&itemHit);
  124.             keepGoing = DoDialogItem(dlog,itemHit);
  125.             }
  126.         
  127.         /*
  128.          *    Do final processing of item values, such as exporting them to caller.
  129.          *    DoDialogItem() has already called AnyBadValues().
  130.          */
  131.         
  132.         if (okay = (itemHit==OK_ITEM)) {        /* Or whatever is equivalent */
  133.             GetDlgLong(dlog, EDIT3, &fileSize);
  134.             }
  135.  
  136.         /* That's all, folks! */
  137.         
  138.         CloseThisDialog(dlog);
  139.         SetPort(oldPort);
  140.         
  141.         return(okay);
  142.     }
  143.  
  144. /*
  145.  *    We have to have a filter function, at the very least so that we can outline
  146.  *    any default button, entertain keyboard editing commands, cmd-period canceling, etc.
  147.  *    Note that you do not need to have a special user item covering the default button
  148.  *    in your dialog item list.
  149.  */
  150.  
  151. static pascal Boolean MyFilter(DialogPtr dlog, EventRecord *evt, short *itemHit)
  152.     {
  153.         Boolean ans=FALSE,doHilite=FALSE; WindowPtr w;
  154.         short type,ch; Handle hndl; Rect box;
  155.         static long then; static Point clickPt;
  156.         
  157.         w = (WindowPtr)(evt->message);
  158.         switch(evt->what) {
  159.             case updateEvt:
  160.                 if (w == dlog) {
  161.                     /* Update our dialog contents */
  162.                     DoDialogUpdate(dlog);
  163.                     ans = TRUE; *itemHit = 0;
  164.                     }
  165.                  else {
  166.                     /*
  167.                      *    Call your main event loop DoUpdate(w) routine here if you
  168.                      *    don't want unsightly holes in background windows caused
  169.                      *    by nested alerts, balloon help, or screen savers (see
  170.                      *    Tech Note #304).
  171.                      */
  172.                     }
  173.                 break;
  174.             case activateEvt:
  175.                 if (w == dlog) {
  176.                     DoDialogActivate(dlog,(evt->modifiers & activeFlag)!=0);
  177.                     *itemHit = 0;
  178.                     }
  179.                  else {
  180.                     /*
  181.                      *    Call your main event loop DoActivate(w) routine here if
  182.                      *    you want to deactivate the former frontmost window, in order
  183.                      *    to unhighlight any selection, scroll bars, etc.
  184.                      */
  185.                     }
  186.                 break;
  187.             case mouseDown:
  188.             case mouseUp:
  189.                 where = evt->where;        /* Make info available to DoDialog() */
  190.                 GlobalToLocal(&where);
  191.                 modifiers = evt->modifiers;
  192.                 ans = CheckUserItems(where,itemHit);
  193.                 break;
  194.             case keyDown:
  195.                 if ((ch=(unsigned char)evt->message)=='\r' || ch==ENTERkey) {
  196.                     *itemHit = OK_ITEM /* Default Item Number here */;
  197.                     doHilite = ans = TRUE;
  198.                     }
  199.                  else if (evt->modifiers & cmdKey) {
  200.                     ch = (unsigned char)evt->message;
  201.                     switch(ch) {
  202.                         case 'x':
  203.                         case 'X':
  204.                             if (TextSelected(dlog))
  205.                                 { SystemEdit(3); ZeroScrap(); DlgCut(dlog); TEToScrap(); }
  206.                              else {
  207.                                 /* Cut from anything else cuttable, like a list */
  208.                                 }
  209.                             break;
  210.                         case 'c':
  211.                         case 'C':
  212.                             if (TextSelected(dlog))
  213.                                 { SystemEdit(3); ZeroScrap(); DlgCopy(dlog); TEToScrap(); }
  214.                              else {
  215.                                 /* Copy from anything else copyable, like a list */
  216.                                 }
  217.                             break;
  218.                         case 'v':
  219.                         case 'V':
  220.                             if (CanPaste(1,'TEXT'))
  221.                                 { TEFromScrap(); DlgPaste(dlog); }
  222.                              else {
  223.                                  /* Deal with any other pasteable scraps here */
  224.                                 }
  225.                             break;
  226.                         case 'a':
  227.                         case 'A':
  228.                             if (((DialogPeek)dlog)->editField >= 0) {
  229.                                 /* Dialog has text edit item: select all */
  230.                                 SelIText(dlog,((DialogPeek)dlog)->editField+1,0,32767);
  231.                                 }
  232.                              else {
  233.                                 }
  234.                             *itemHit = 0;
  235.                             break;
  236.                         case '.':
  237.                             *itemHit = CANCEL_ITEM;
  238.                             doHilite = TRUE;
  239.                             break;
  240.                         }
  241.                     ans = TRUE;        /* Other cmd-chars ignored */
  242.                     }
  243.                 break;
  244.             }
  245.         if (doHilite) {
  246.             GetDItem(dlog,*itemHit,&type,&hndl,&box);
  247.             /* Reality check */
  248.             if (type == (btnCtrl+ctrlItem)) {
  249.                 long soon = TickCount() + 7;        /* Or whatever feels right */
  250.                 HiliteControl((ControlHandle)hndl,1);
  251.                 while (TickCount() < soon) ;        /* Leave hilited for a bit */
  252.                 }
  253.             }
  254.         return(ans);
  255.     }
  256.  
  257. /*
  258.  * Mouse down event:
  259.  * Check if it's in some user item, and convert to itemHit if appropriate.
  260.  */
  261.  
  262. static Boolean CheckUserItems(Point where, short *itemHit)
  263.     {
  264.         return(FALSE);
  265.     }
  266.  
  267. /*
  268.  * Redraw the contents of this dialog due to update event.
  269.  * If you have not installed UserItem draw routines, you should redraw
  270.  * them explicitly here; otherwise, UpdtDialog() will call your routines.
  271.  */
  272.  
  273. static void DoDialogUpdate(DialogPtr dlog)
  274.     {
  275.         GrafPtr oldPort;
  276.  
  277.         GetPort(&oldPort); SetPort(dlog);
  278.         BeginUpdate(dlog);
  279.  
  280.         UpdtDialog(dlog,dlog->visRgn);
  281.         FrameDefault(dlog,BUT1_OK,TRUE);
  282.  
  283.         EndUpdate(dlog);
  284.         SetPort(oldPort);
  285.     }
  286.  
  287. /*
  288.  * Activate event: Activate or deactivate this dialog and any items in it
  289.  */
  290.  
  291. static void DoDialogActivate(DialogPtr dlog, int activ)
  292.     {
  293.         SetPort(dlog);
  294.     }
  295.  
  296. /*
  297.  * Build this dialog's window on desktop, and install initial item values.
  298.  * Return the dlog opened, or NIL if error (no resource, no memory).
  299.  */
  300.  
  301. static DialogPtr OpenThisDialog()
  302.     {
  303.         short type; Handle hndl; Rect box; GrafPtr oldPort;
  304.         DialogPtr dlog; unsigned char *p,str[256];
  305.  
  306.         GetPort(&oldPort);
  307.         dlog = GetNewDialog(thisDialogID,NIL,FRONT_WINDOW);
  308.         if (dlog == NIL) { SysBeep(1); return(NIL); }    /* Poor man's error message */
  309.  
  310.         CenterWindow(dlog,0);
  311.         SetPort(dlog);
  312.  
  313.         /* Fill in dialog's values here */
  314.  
  315.         PutDlgLong(dlog,EDIT3,fileSize, TRUE);
  316.  
  317.         ShowWindow(dlog);
  318.         return(dlog);
  319.  
  320.     }
  321.  
  322. /*
  323.  * Clean up any allocated stuff, and return dialog to primordial mists
  324.  */
  325.  
  326. static void CloseThisDialog(DialogPtr dlog)
  327.     {
  328.         DisposDialog(dlog);    /* Call CloseDialog if you provide storage to GetNewDialog */
  329.     }
  330.  
  331. /*
  332.  * Deal with user clicking on an item in this dialog, either modal or non-modal.
  333.  * The local point is in where; modifiers in modifiers.
  334.  * Returns whether or not the dialog should be closed (keepGoing).
  335.  */
  336.  
  337. static int DoDialogItem(DialogPtr dlog, short itemHit)
  338.     {
  339.         short type,okay=FALSE,keepGoing=TRUE,val;
  340.         Handle hndl; Rect box; Point pt;
  341.         unsigned char *p,str[256];
  342.  
  343.         if (itemHit<1 || itemHit>=LASTITEM)
  344.             return(keepGoing);                /* Only legal items, please */
  345.  
  346.         GetDItem(dlog,itemHit,&type,&hndl,&box);
  347.         switch(type) {
  348.             case ctrlItem+btnCtrl:
  349.                 switch(itemHit) {
  350.                     case BUT1_OK:
  351.                         keepGoing = FALSE; okay = TRUE;
  352.                         break;
  353.                     case BUT2_Cancel:
  354.                         keepGoing = FALSE;
  355.                         break;
  356.                     }
  357.                 break;
  358.             case ctrlItem+chkCtrl:
  359.                 break;
  360.             case ctrlItem+radCtrl:
  361.                 break;
  362.             case ctrlItem+resCtrl:
  363.                 break;
  364.             case statText:
  365.                 switch(itemHit) {
  366.                     case STXT4_File:        /* NOT Enabled */
  367.                         break;
  368.                     case STXT5_K:        /* NOT Enabled */
  369.                         break;
  370.                     }
  371.                 break;
  372.             case editText:
  373.                 switch(itemHit) {
  374.                     case EDIT3:
  375.                         break;
  376.                     }
  377.                 break;
  378.             case iconItem:
  379.                 break;
  380.             case picItem:
  381.                 break;
  382.             case userItem:
  383.                 break;
  384.             }
  385.  
  386.         if (okay) keepGoing = AnyBadValues(dlog);
  387.         return(keepGoing);
  388.     }
  389.  
  390. /*
  391.  * Pull values out of dialog items and deliver TRUE if any of them are
  392.  * illegal or inconsistent; otherwise deliver FALSE.  If any values are bad,
  393.  * you should inform your user about the problem here before delivering TRUE.
  394.  * If any items are missing values, this is the place to assign any defaults.
  395.  */
  396.  
  397. static int AnyBadValues(DialogPtr dlog)
  398.     {
  399.         char str[256]; short val,len;
  400.  
  401.         if (GetDlgString(dlog,EDIT3,str)) {
  402.             /* Got a string (can also call GetDlgWord(), etc. here) */
  403.             }
  404.         else {
  405.             /* Field was empty */
  406.             }
  407.         return(FALSE);
  408.     }
  409.  
  410. /*••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••*/
  411.  
  412. /*
  413.  *  The following are various utility routines for general dialog management.
  414.  *  Typically, you'll want to keep them in a library that is available to all
  415.  *  your dialog modules; however, they are included here (and declared static)
  416.  *  as a private library so that you can quickly compile this file for testing.
  417.  */
  418.  
  419. #define _PrivateLibraries_
  420. #ifdef  _PrivateLibraries_
  421.  
  422. /*
  423.  *    Center a given window, w, horizontally in the main screen, top pixels from
  424.  *    the top, or centered vertically if top is 0.  The window should be invisible.
  425.  */
  426.  
  427. static void CenterWindow(WindowPtr w, int top)
  428.     {
  429.         Rect scr; Point p;
  430.         int rsize,size,margin,xoff,yoff;
  431.  
  432.         scr = qd.screenBits.bounds;
  433.         SetPort(w);
  434.         p.h = w->portRect.left; p.v = w->portRect.top;
  435.         LocalToGlobal(&p);
  436.  
  437.         size = scr.right - scr.left;
  438.         rsize = w->portRect.right - w->portRect.left;
  439.         margin = size - rsize;
  440.         if (margin > 0) {
  441.             margin >>= 1;
  442.             p.h = scr.left + margin;
  443.             }
  444.         size = scr.bottom - scr.top;
  445.         rsize = w->portRect.bottom - w->portRect.top;
  446.         margin = size - rsize;
  447.         if (margin > 0) {
  448.             margin >>= 1;
  449.             p.v = scr.top + margin;
  450.             }
  451.         MoveWindow(w,p.h,top?top:p.v,FALSE);
  452.     }
  453.  
  454. /* Local C string length routine */
  455.  
  456. static long strlen(register char *str)
  457.     {
  458.         register char *p;
  459.  
  460.         p = str;
  461.         while (*p++) ;
  462.         return((long)(--p - str));
  463.     }
  464.  
  465. /* Convert in place a Pascal string to C string, and deliver its address */
  466.  
  467. static char *PascalToC(char *str)
  468.     {
  469.         register char *p,*q,*end;
  470.  
  471.         end = str + *(unsigned char *)str;
  472.         q = (p=str) + 1;
  473.         while (p < end) *p++ = *q++;
  474.         *p = '\0';
  475.         return(str);
  476.     }
  477.  
  478. /*
  479.  *    Convert in place a C string to Pascal string, and deliver its address.
  480.  *    The C string should not be greater than 255 chars in length, or the
  481.  *    resulting Pascal string will be truncated to 255 chars.
  482.  */
  483.  
  484. static char *CToPascal(char *str)
  485.     {
  486.         register char *p,*q;
  487.         register long len;
  488.  
  489.         len = strlen(str);
  490.         if (len > 255) len = 255;
  491.         p = str + len;
  492.         q = p-1;
  493.         while (p != str) *p-- = *q--;
  494.         *str = len;
  495.         return(str);
  496.     }
  497.  
  498. /* Dialog Item Stuffers */
  499.  
  500. /*
  501.  *    Install a given Pascal string, str, into the given static or edit text item
  502.  *    in the dialog, dlog.  If the item is an edit text item, leave the installed
  503.  *    text selected or not according to the value of sel (TRUE or FALSE).
  504.  */
  505.  
  506. static void PutDlgString(DialogPtr dlog, int item, char *str, int sel)
  507.     {
  508.         short type; Handle hndl; Rect box;
  509.  
  510.         GetDItem(dlog,item,&type,&hndl,&box);
  511.         SetIText(hndl, (void*)str);
  512.         if (type == editText)
  513.             SelIText(dlog,item,sel?0:32767,32767);
  514.         InvalRect(&box);
  515.     }
  516.  
  517. /*
  518.  *    Install a given decimal long value into the static or edit text item of the
  519.  *    given dialog, dlog.  If the item is an edit text item, leave the installed
  520.  *    text for the number selected or not according to sel (TRUE or FALSE).
  521.  */
  522.  
  523. static void PutDlgLong(DialogPtr dlog, int item, long val, int sel)
  524.     {
  525.         char str[32];
  526.  
  527.         NumToString(val, (void*)str);
  528.         PutDlgString(dlog,item,str,sel);
  529.     }
  530.  
  531. /*
  532.  *    Same as above, only for an int (word) decimal number.
  533.  */
  534.  
  535. static void PutDlgWord(DialogPtr dlog, int item, int val, int sel)
  536.     {
  537.         PutDlgLong(dlog,item,(long)val,sel);
  538.     }
  539.  
  540. /*
  541.  *    Set the given check box or radio button item of the given dialog, dlog, to
  542.  *    on or off, according to val.
  543.  */
  544.  
  545. static void PutDlgChkRadio(DialogPtr dlog, int item, int val)
  546.     {
  547.         short type; Handle hndl; Rect box;
  548.  
  549.         GetDItem(dlog,item,&type,&hndl,&box);
  550.         SetCtlValue((ControlHandle)hndl,val!=0);
  551.     }
  552.  
  553. /*
  554.  *    Deliver the value of the checkbox or radio button item of the given dialog.
  555.  */
  556.  
  557. static int GetDlgChkRadio(DialogPtr dlog, int item)
  558.     {
  559.         short type; Handle hndl; Rect box;
  560.         
  561.         GetDItem(dlog,item,&type,&hndl,&box);
  562.         return(GetCtlValue((ControlHandle)hndl) != 0);
  563.     }
  564.  
  565. /* Dialog Item Unstuffers */
  566.  
  567. /*
  568.  *    Retrieve the value of an edit text item in a given dialog, placing the
  569.  *    resulting Pascal string in the buffer, str, which is assumed large enough
  570.  *    to hold the text (256 bytes max).  If item is the number of a static text
  571.  *    item, the empty string is delivered.  Delivers TRUE or FALSE according to
  572.  *    whether or not the text so delivered was empty.  
  573.  */
  574.  
  575. static int GetDlgString(DialogPtr dlog, int item, char *str)
  576.     {
  577.         short type; Handle hndl; Rect box;
  578.  
  579.         GetDItem(dlog,item,&type,&hndl,&box);
  580.         if (type == editText) GetIText(hndl, (void*)str);
  581.          else                 *str = 0;
  582.         return(*str != 0);
  583.     }
  584.  
  585. /*
  586.  *    Retrieve the value of an edit text item in a given dialog, converting the
  587.  *    Pascal string to a long and setting *val to it.  Delivers TRUE or FALSE
  588.  *    according to whether or not the text so delivered was empty.  If FALSE,
  589.  *    *val is set to 0; if TRUE, *val is set to whatever StringToNum() says the
  590.  *    value is, even if the text contains non-numerical characters.
  591.  */
  592.  
  593. static int GetDlgLong(DialogPtr dlog, int item, long *val)
  594.     {
  595.         int ans; char str[256];
  596.  
  597.         *val = 0;
  598.         if (ans = GetDlgString(dlog,item,str))
  599.             StringToNum((void*)str,val);
  600.         return(ans);
  601.         }
  602.  
  603. /* Same as above, only delivers the value of a word */
  604.  
  605. static int GetDlgWord(DialogPtr dlog, int item, short *val)
  606.     {
  607.         int ans; long num;
  608.  
  609.         *val = 0;
  610.         if (ans = GetDlgLong(dlog,item,&num))
  611.             *val = num;
  612.         return(ans);
  613.     }
  614.  
  615. /*
  616.  *    Deliver the number of the current editText item in given dialog if any text
  617.  *    is selected in it, or 0 if none selected.
  618.  */
  619.  
  620. int TextSelected(DialogPtr dlog)
  621.     {
  622.         register TEHandle textH; int item = 0;
  623.         
  624.         textH = ((DialogPeek)dlog)->textH;
  625.         if (*textH)
  626.             if ( (*textH)->selStart != (*textH)->selEnd )
  627.                 item = ((DialogPeek)dlog)->editField+1;
  628.         return(item);
  629.     }
  630.  
  631. /*
  632.  *  If any of the variable argument scrap types are available for pasting from
  633.  *  the scrap, deliver the first one.  Otherwise, deliver 0.  For example,
  634.  *    
  635.  *      if (whichType = CanPaste(3,'TEXT','PICT','STUF')) ...
  636.  *
  637.  *  There can be any number of types in the list, as long as the preceding count, n,
  638.  *  is correct.
  639.  */
  640.  
  641. static OSType CanPaste(int n, ...)
  642.     {
  643.         register OSType nextType,ans = 0L;
  644.         long err,offset;
  645.         va_list nextArg;
  646.         
  647.         va_start(nextArg,n);
  648.         nextType = va_arg(nextArg, OSType);
  649.         
  650.         while (n-- > 0) {
  651.             err = GetScrap(NIL, nextType, &offset);
  652.             if (err >= -1) {
  653.                 ans = nextType;
  654.                 break;
  655.                 }
  656.             nextType = va_arg(nextArg, OSType);
  657.             }
  658.         
  659.         va_end(nextArg);
  660.         return(ans);
  661.     }
  662.  
  663. /*
  664.  *    Frame or unframe a default dialog item (presumed a button) in given dialog.
  665.  *    Note that you don't need to use an extra user item to do this unless you
  666.  *    are doing some sort of non-standard default highlighting (not recommended).
  667.  */
  668.  
  669. static void FrameDefault(DialogPtr dlog, int item, int frame)
  670.     {
  671.         short type; Handle hndl; Rect box;
  672.         GrafPtr oldPort; PenState oldPen;
  673.         
  674.         GetPort(&oldPort); SetPort(dlog);
  675.         GetPenState(&oldPen);
  676.         
  677.         GetDItem(dlog,item,&type,&hndl,&box);
  678.         InsetRect(&box,-4,-4);
  679.         
  680.         PenSize(3,3);
  681.         if (frame) PenPat(&qd.black);        /* Paint frame */
  682.          else      PenPat(&qd.white);        /* Erase frame */
  683.         FrameRoundRect(&box,16,16);
  684.         
  685.         SetPenState(&oldPen);
  686.         SetPort(oldPort);
  687.     }
  688.  
  689. /*
  690.  *    Get rectangle, *panel, for a given item (usually a user or picture item)
  691.  *    and then hide the item so that it doesn't interfere with mouse clicking.
  692.  *    This lets you stop worrying about the item order any user or pict items that
  693.  *    obscure other items in the item list, which can affect how the DialogMgr
  694.  *    returns itemHits.
  695.  */
  696.  
  697. static void GetDlgPanel(DialogPtr dlog, int item, Rect *panel)
  698.     {
  699.         short type; Handle hndl;
  700.         
  701.         GetDItem(dlog,item,&type,&hndl,panel);
  702.         HideDItem(dlog,item);
  703.     }
  704.  
  705. #endif
  706.  
  707.